/**
 * Copyright (C) 2012 Oleg Anastassov <o.anastasov@gmail.com>
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kz.kstu.ent.desktop.ui.frame;

import kz.kstu.ent.app.context.AppContext;
import kz.kstu.ent.app.delegate.api.ExamDelegate;
import kz.kstu.ent.app.delegate.impl.ExamDelegateImpl;
import kz.kstu.ent.business.entity.Exam;
import kz.kstu.ent.business.entity.security.Account;
import kz.kstu.ent.desktop.chart.bar.AverageMarkBar;
import kz.kstu.ent.desktop.chart.info.BarChartInfo;
import kz.kstu.ent.desktop.common.ChartBuilder;
import kz.kstu.ent.desktop.common.DatasetConverter;
import kz.kstu.ent.desktop.images.GUIFactory;
import kz.kstu.ent.desktop.images.GUIIcon;
import kz.kstu.ent.desktop.ui.ControllerLife;
import kz.kstu.ent.desktop.ui.dialog.about.AboutDialog;
import kz.kstu.ent.desktop.ui.dialog.environment.EnvironmentDialog;
import kz.kstu.ent.desktop.ui.dialog.grade.AllGradesDialog;
import kz.kstu.ent.desktop.ui.dialog.regular.RegularTestingDialog;
import kz.kstu.ent.desktop.ui.dialog.security.ChangePasswordDialog;
import kz.kstu.ent.desktop.ui.dialog.security.RegisterUserDialog;
import kz.kstu.ent.desktop.ui.dialog.students.AllStudentsDialog;
import kz.kstu.ent.desktop.ui.page.DashboardPage;
import kz.kstu.ent.desktop.util.GUIUtils;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;


/**
 * Date: 28.08.12
 * Time: 20:37
 *
 * @author Oleg Anastassov
 */
public class ApplicationFrame extends JFrame implements ControllerLife {

    private Account account;

    private static final String TITLE = "Технический лицей :: " +
            "Анализ результатов предварительной сдачи " +
            "Единого Национального Тестирования";

    // КЛАСС
    private static final String MENU_LYCEUM = "Лицей";
    private static final String MI_STUDENTS = "Ученики";
    private static final String MI_GRADES = "Классы";
    private static final String MI_SUBJECTS = "Предметы";

    // ТЕСТИРОВАНИЕ
    private static final String MENU_ENT = "Тестирование";
    private static final String MI_REGULAR_ENT = "Очередная сдача ЕНТ";

    // ОТЧЕТЫ
    private static final String MENU_REPORTS = "Отчеты";
    private static final String MI_REPORT_STAND = "Информация на стенд (демо)";
    private static final String MI_REPORT_AVERAGE = "Общий средний балл";
    private static final String MENU_REPORT_SUBJECTS = "По предметам";
    private static final String MI_REPORT_MATH = "Математика";
    private static final String MI_REPORT_RUSSIAN = "Русский язык";
    private static final String MI_REPORT_KAZAKH = "Казахский язык";
    private static final String MI_REPORT_KAZAKH_HISTORY = "История Казахстана";

    private static final String MENU_SETTINGS = "Настройки";
    private static final String MENU_HELP = "Помощь";

    // ПРОФИЛЬ
    private static final String MENU_ITEM_CHANGE_PASSWORD = "Сменить пароль...";

    // НАСТРОЙКИ
    private static final String MENU_ITEM_ADD_USER = "Регистрация пользователя...";
    private static final String MENU_ITEM_ENVIRONMENT = "Настройки окружения...";

    // ПОМОЩЬ
    private static final String MENU_ITEM_CONTENT = "Справка";
    private static final String MENU_ITEM_ABOUT = "О программе...";

    private JMenuItem miStudents;
    private JMenuItem miGrades;
    private JMenuItem miSubjects;
    private JMenuItem miRegularTesting;
    private JMenuItem miReportStandDemo;
    private JMenuItem miReportSubjectsAverage;
    private JMenuItem miReportMath;
    private JMenuItem miReportRussian;
    private JMenuItem miReportKazakh;
    private JMenuItem miReportKazakhHistory;

    private JMenuItem menuItemChangePassword;

    private JMenuItem menuItemContent;
    private JMenuItem menuItemUserManagement;
    private JMenuItem menuItemEnvironment;
    private JMenuItem menuItemAbout;

    private DashboardPage dashboardPage = new DashboardPage();

    public void initStaticComponents() {
        account = AppContext.getInstance().getAccount();

        initMenuBar();
        initIcons();
        initListeners();
        initAccelerators();
        initWindow();

        setContentPane(dashboardPage.getRootPanel());
        dashboardPage.initData();
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    }

    private void initIcons() {
        setIconImage(
                GUIFactory.getImage(GUIIcon.LOGO)
        );
    }

    @Override
    public void initData() {

    }

    private void initMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        // ЛИЦЕЙ
        JMenu menuLyceum = new JMenu(MENU_LYCEUM);
        menuLyceum.setIcon(
                GUIFactory.getIcon(GUIIcon.CLASS)
        );
        miStudents = new JMenuItem(
                MI_STUDENTS,
                GUIFactory.getIcon(GUIIcon.STUDENTS)
        );
        miGrades = new JMenuItem(
                MI_GRADES,
                GUIFactory.getIcon(GUIIcon.USER_GROUP)
        );
        miSubjects = new JMenuItem(
                MI_SUBJECTS,
                GUIFactory.getIcon(GUIIcon.SUBJECTS)
        );
        menuLyceum.add(miGrades);
        menuLyceum.add(miStudents);
        menuLyceum.add(miSubjects);
        menuBar.add(menuLyceum);

        // ТЕСТИРОВАНИЕ
        JMenu menuTest = new JMenu(MENU_ENT);
        menuTest.setIcon(
                GUIFactory.getIcon(GUIIcon.ENT)
        );
        miRegularTesting = new JMenuItem(
                MI_REGULAR_ENT,
                GUIFactory.getIcon(GUIIcon.REGULAR_ENT)
        );
        menuTest.add(miRegularTesting);
        menuBar.add(menuTest);

        // ОТЧЕТЫ
        JMenu menuReports = new JMenu(MENU_REPORTS);
        menuReports.setIcon(
                GUIFactory.getIcon(GUIIcon.REPORT)
        );
        miReportStandDemo = new JMenuItem(
                MI_REPORT_STAND,
                GUIFactory.getIcon(GUIIcon.STAND)
        );
        miReportSubjectsAverage = new JMenuItem(
                MI_REPORT_AVERAGE,
                GUIFactory.getIcon(GUIIcon.LOGO)
        );
        JMenu subjectAverageMenu = new JMenu(MENU_REPORT_SUBJECTS);
        subjectAverageMenu.setIcon(
                GUIFactory.getIcon(GUIIcon.SUBJECTS_MAIN)
        );
        miReportMath = new JMenuItem(
                MI_REPORT_MATH,
                GUIFactory.getIcon(GUIIcon.MATH)
        );
        miReportRussian = new JMenuItem(
                MI_REPORT_RUSSIAN,
                GUIFactory.getIcon(GUIIcon.RUSSIAN)
        );
        miReportKazakh = new JMenuItem(
                MI_REPORT_KAZAKH,
                GUIFactory.getIcon(GUIIcon.KAZAKH)
        );
        miReportKazakhHistory = new JMenuItem(
                MI_REPORT_KAZAKH_HISTORY,
                GUIFactory.getIcon(GUIIcon.KAZAKH_HISTORY)
        );
        subjectAverageMenu.add(miReportMath);
        subjectAverageMenu.add(miReportRussian);
        subjectAverageMenu.add(miReportKazakh);
        subjectAverageMenu.add(miReportKazakhHistory);
        menuReports.add(miReportSubjectsAverage);
        menuReports.addSeparator();
        menuReports.add(subjectAverageMenu);
        menuReports.addSeparator();
        menuReports.add(miReportStandDemo);
        menuBar.add(menuReports);

        // НАСТРОЙКИ
        JMenu settingsMenu = new JMenu(MENU_SETTINGS);
        settingsMenu.setIcon(
                GUIFactory.getIcon(GUIIcon.SETTINGS)
        );
        menuItemChangePassword = new JMenuItem(
                MENU_ITEM_CHANGE_PASSWORD,
                GUIFactory.getIcon(GUIIcon.KEY)
        );
        menuItemUserManagement = new JMenuItem(
                MENU_ITEM_ADD_USER,
                GUIFactory.getIcon(GUIIcon.USER_GROUP)
        );
        menuItemEnvironment = new JMenuItem(
                MENU_ITEM_ENVIRONMENT,
                GUIFactory.getIcon(GUIIcon.ENVIRONMENT)
        );
        settingsMenu.add(menuItemChangePassword);
        if (account.isAdmin()) {
            settingsMenu.add(menuItemUserManagement);
        }
        settingsMenu.addSeparator();
        settingsMenu.add(menuItemEnvironment);
        menuBar.add(settingsMenu);

        // ПОМОЩЬ
        JMenu helpMenu = new JMenu(MENU_HELP);
        helpMenu.setIcon(
                GUIFactory.getIcon(GUIIcon.CONTENT)
        );
        menuItemContent = new JMenuItem(
                MENU_ITEM_CONTENT,
                GUIFactory.getIcon(GUIIcon.CONTENT)
        );
        menuItemAbout = new JMenuItem(
                MENU_ITEM_ABOUT,
                GUIFactory.getIcon(GUIIcon.ABOUT)
        );
        helpMenu.add(menuItemContent);
        helpMenu.addSeparator();
        helpMenu.add(menuItemAbout);
        menuBar.add(helpMenu);

        setJMenuBar(menuBar);
    }

    private void initWindow() {
        setTitle(TITLE);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setResizable(false);
        setSize(GUIUtils.preferredStartupScreenSize());
        setMinimumSize(GUIUtils.preferredStartupScreenSize());
    }

    private void initListeners() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                close();
            }
        });
        miGrades.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AllGradesDialog dialog = new AllGradesDialog();
                dialog.initStaticComponents();
                dialog.initData();
                GUIUtils.centerAndShow(dialog);
            }
        });
        miStudents.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AllStudentsDialog dialog = new AllStudentsDialog();
                dialog.initStaticComponents();
                dialog.initData();
                GUIUtils.centerAndShow(dialog);
            }
        });
        miRegularTesting.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                RegularTestingDialog dialog = new RegularTestingDialog();
                dialog.initStaticComponents();
                dialog.initData();
                GUIUtils.centerAndShow(dialog);
            }
        });
        miReportStandDemo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFreeChart demoChart = ChartBuilder.buildDemo();
                ChartFrame chartFrame = new ChartFrame("Информация на стенд :: Средний балл", demoChart);
                chartFrame.setIconImage(GUIFactory.getImage(GUIIcon.STAND));
                chartFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
                chartFrame.setSize(new Dimension(600, 400));
                chartFrame.setExtendedState(chartFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
                GUIUtils.centerAndShow(chartFrame);
            }
        });
        miReportSubjectsAverage.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExamDelegate delegate = new ExamDelegateImpl();
                List<Exam> exams = delegate.findAll(Exam.class);
                DatasetConverter converter = new DatasetConverter();
                DefaultCategoryDataset dataset = converter.convertExamsForBarChart(exams);

                AverageMarkBar bar = new AverageMarkBar(
                        new BarChartInfo(
                                "Средний балл",
                                "Даты проведения тестирования",
                                null,
                                PlotOrientation.HORIZONTAL
                        ),
                        dataset
                );
                JFreeChart chart = bar.build();

                ChartFrame chartFrame = new ChartFrame("Информация на стенд :: Средний балл", chart);
                chartFrame.setIconImage(GUIFactory.getImage(GUIIcon.STAND));
                chartFrame.setSize(new Dimension(600, 400));
                chartFrame.setExtendedState(chartFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
                GUIUtils.centerAndShow(chartFrame);
            }
        });
        miReportMath.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExamDelegate delegate = new ExamDelegateImpl();
                List<Exam> exams = delegate.findAll(Exam.class);
                DatasetConverter converter = new DatasetConverter();
                DefaultCategoryDataset dataset = converter.convertMathResults(exams);

                AverageMarkBar bar = new AverageMarkBar(
                        new BarChartInfo(
                                "Средний балл по математике",
                                "Даты проведения тестирования",
                                null,
                                PlotOrientation.VERTICAL
                        ),
                        dataset
                );
                JFreeChart chart = bar.build();

                ChartFrame chartFrame = new ChartFrame("Информация на стенд :: Средний балл по математике", chart);
                chartFrame.setIconImage(GUIFactory.getImage(GUIIcon.STAND));
                chartFrame.setSize(new Dimension(600, 400));
                chartFrame.setExtendedState(chartFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
                GUIUtils.centerAndShow(chartFrame);
            }
        });
        miReportRussian.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExamDelegate delegate = new ExamDelegateImpl();
                List<Exam> exams = delegate.findAll(Exam.class);
                DatasetConverter converter = new DatasetConverter();
                DefaultCategoryDataset dataset = converter.convertRussianResults(exams);

                AverageMarkBar bar = new AverageMarkBar(
                        new BarChartInfo(
                                "Средний балл по Русскому языку",
                                "Даты проведения тестирования",
                                null,
                                PlotOrientation.VERTICAL
                        ),
                        dataset
                );
                JFreeChart chart = bar.build();

                ChartFrame chartFrame = new ChartFrame("Информация на стенд :: Средний балл по Русскому языку", chart);
                chartFrame.setIconImage(GUIFactory.getImage(GUIIcon.STAND));
                chartFrame.setSize(new Dimension(600, 400));
                chartFrame.setExtendedState(chartFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
                GUIUtils.centerAndShow(chartFrame);
            }
        });
        miReportKazakh.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExamDelegate delegate = new ExamDelegateImpl();
                List<Exam> exams = delegate.findAll(Exam.class);
                DatasetConverter converter = new DatasetConverter();
                DefaultCategoryDataset dataset = converter.convertKazakhResults(exams);

                AverageMarkBar bar = new AverageMarkBar(
                        new BarChartInfo(
                                "Средний балл по Казахскому языку",
                                "Даты проведения тестирования",
                                null,
                                PlotOrientation.VERTICAL
                        ),
                        dataset
                );
                JFreeChart chart = bar.build();

                ChartFrame chartFrame = new ChartFrame("Информация на стенд :: Средний балл по Казахскому языку", chart);
                chartFrame.setIconImage(GUIFactory.getImage(GUIIcon.STAND));
                chartFrame.setSize(new Dimension(600, 400));
                chartFrame.setExtendedState(chartFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
                GUIUtils.centerAndShow(chartFrame);
            }
        });
        miReportKazakhHistory.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExamDelegate delegate = new ExamDelegateImpl();
                List<Exam> exams = delegate.findAll(Exam.class);
                DatasetConverter converter = new DatasetConverter();
                DefaultCategoryDataset dataset = converter.convertKazakhHistoryResults(exams);

                AverageMarkBar bar = new AverageMarkBar(
                        new BarChartInfo(
                                "Средний балл по Истории Казахстана",
                                "Даты проведения тестирования",
                                null,
                                PlotOrientation.VERTICAL
                        ),
                        dataset
                );
                JFreeChart chart = bar.build();

                ChartFrame chartFrame = new ChartFrame("Информация на стенд :: Средний балл по Истории Казахстана", chart);
                chartFrame.setIconImage(GUIFactory.getImage(GUIIcon.STAND));
                chartFrame.setSize(new Dimension(600, 400));
                chartFrame.setExtendedState(chartFrame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
                GUIUtils.centerAndShow(chartFrame);
            }
        });
        menuItemChangePassword.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ChangePasswordDialog dialog = new ChangePasswordDialog();
                dialog.changePassword();
            }
        });
        menuItemUserManagement.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                RegisterUserDialog registerDialog = new RegisterUserDialog();
                registerDialog.initStaticComponents();
            }
        });
        menuItemEnvironment.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                EnvironmentDialog dialog = new EnvironmentDialog();
                dialog.initStaticComponents();
                dialog.initData();
                GUIUtils.centerAndShow(dialog);
            }
        });
        menuItemAbout.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AboutDialog dialog = new AboutDialog();
                dialog.initStaticComponents();
                GUIUtils.centerAndShow(dialog);
            }
        });
    }

    private void initAccelerators() {
        miStudents.setAccelerator(
                KeyStroke.getKeyStroke("control alt L")
        );
        miGrades.setAccelerator(
                KeyStroke.getKeyStroke("control alt G")
        );
        miSubjects.setAccelerator(
                KeyStroke.getKeyStroke("control alt P")
        );
        miReportStandDemo.setAccelerator(
                KeyStroke.getKeyStroke("control alt S")
        );
        menuItemContent.setAccelerator(
                KeyStroke.getKeyStroke("F1")
        );
    }

    public void close() {
        dispose();
        System.exit(0);
    }
}
